package com.guochu.common;

import com.guochu.common.infrastructure.Identity;
import com.guochu.org.service.UserService;
import com.guochu.utils.redis.RedisUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class AuthService {
    /**
     * 过期分钟
     */
    private int expireMinutes = 1440;

    /**
     * token时间戳有效分钟
     */
    private int timestampMinutes = 1;

    /**
     * token缓存的前缀
     */
    private String tokenPrefix = "identityToken_";

    /**
     * 缓存工具类
     */
    @Autowired
    RedisUtil redis;

    @Autowired
    UserService userService;

    public String getToken(Identity identity) {
        String token = tokenPrefix + UUID.randomUUID();
        HashMap<String, Object> map1 = beanToMap(identity);
        redis.setHashMap(token, map1);
        return token;
    }

    public boolean refreshToken(Identity identity) {
        String token = getTokenString();
        if (token != null && !"null".equals(token) && !"".equals(token)) {
            HashMap<String, Object> map1 = beanToMap(identity);
            redis.setHashMap(token, map1);
        }
        return false;
    }

    /**
     * 判断请求头信息是否存在及是否在有效期
     *
     * @param token
     * @param timestamp
     * @param sign
     * @return
     */
    public boolean checkToken(String token, String timestamp, String sign) {

        //判断Token是否存在
        if (redis.exists(token)) {
            //判断调用时间是否在有效期内
            Calendar c = Calendar.getInstance();
            //1分钟内调用才成功
            c.add(Calendar.MINUTE, -timestampMinutes);
            Date timestampDate = new Date();
            timestampDate.setTime(Long.parseLong(timestamp));
            if (timestampDate != null && timestampDate.compareTo(c.getTime()) > 0) {
                String checkSign = DigestUtils.md5Hex(timestamp + token);
                if (checkSign.equals(sign)) {
                    //延长过期时间
//                        long redisExpireSeconds = expireMinutes * 6000;
//                        redis.setExpire(token, redisExpireSeconds, TimeUnit.SECONDS);
//                        redis.setExpire(getIdentity().getLogin().getAccount() + "loginToken", redisExpireSeconds, TimeUnit.SECONDS);
                    return true;
                }
            }
        }

        return false;
    }

    public void removeToken(String token) {
        redis.remove(token);
    }

    /**
     * 获取当前Token
     *
     * @return
     */
    public String getTokenString() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("token");

        if (token == null || "null".equals(token) || "".equals(token)) {
            // 手机端的上传图片控件无法设置header ，所以加上这句。  打开编辑页面，为了使用model绑定，需要在layer弹出时增加参数token
            token = request.getParameter("token");
        }

        return token;
    }

    public Identity getIdentity() {
        String token = getTokenString();
        if (token != null && !"null".equals(token) && !"".equals(token)) {
            Map<String, Object> map = redis.getHashMap(token);
            if (null != map) {
                return mapToBean(map, new Identity());
            }
        }
        return null;
    }

    public Identity updateIdentity() {
        String token = getTokenString();
        if (token != null && !"null".equals(token) && !"".equals(token)) {


            Map<String, Object> map = redis.getHashMap(token);
            if (null != map) {
                return mapToBean(map, new Identity());
            }
        }
        return null;
    }


    /**
     * 自主登出
     *
     * @param token
     */
    public void loginOut(String token) {

//        if (redis.exists(token)) {
//            Identity identity = getIdentity();
//
//            if (identity != null) {
//                redis.remove(identity.getLogin().getAccount());
//            }
//        }

        redis.remove(token);
    }

    /**
     * 将对象装换为map
     *
     * @param bean
     * @return
     */
    public static <T> HashMap<String, Object> beanToMap(T bean) {
        HashMap<String, Object> map = new HashMap();
        if (bean != null) {
            BeanMap beanMap = BeanMap.create(bean);
            for (Object key : beanMap.keySet()) {
                map.put(key + "", beanMap.get(key));
            }
        }
        return map;
    }

    /**
     * 将map装换为javabean对象
     *
     * @param map
     * @param bean
     * @return
     */
    public static <T> T mapToBean(Map<String, Object> map, T bean) {
        BeanMap beanMap = BeanMap.create(bean);
        beanMap.putAll(map);
        return bean;
    }
}
